//
//  YSCoverViewController.m
//  YSBookRead
//
//  Created by MOLBASE on 2018/11/7.
//  Copyright © 2018年 YangShen. All rights reserved.
//

#import "YSCoverViewController.h"

#define kControllerWidth  self.view.frame.size.width
#define kControllerHeight self.view.frame.size.height
/// 动画时间
static const CGFloat kAnimateDuration = 0.20;

@interface YSCoverViewController () <UIGestureRecognizerDelegate>

/// 左拉右拉手势
@property (nonatomic, strong) UIPanGestureRecognizer *pan;
/// 点击手势
@property (nonatomic, strong) UITapGestureRecognizer *tap;
/// 手势触发点是否在左边（点左边拿上一个控制器 点右边拿下一个控制器）
@property (nonatomic, assign) BOOL isTapLeft;
/// 判断执行pan手势
@property (nonatomic, assign) BOOL isPan;
/// 手势是否重新开始识别
@property (nonatomic, assign) BOOL isPanBegin;
/// 动画状态
@property (nonatomic, assign) BOOL isAnimateChange;
/// 临时控制器 通过代理获取回来的控制器 还没有完全展示出来的控制器
@property (nonatomic, strong, nullable) UIViewController *pendingViewController;
/// 移动中的触摸位置
@property (nonatomic, assign) CGPoint moveTouchPoint;
/// 移动中的差值
@property (nonatomic,assign) CGFloat moveSpaceX;

@end

@implementation YSCoverViewController

- (instancetype)init {
    if (self = [super init]) {
        _openAnimate = YES;
        _panGestureRecognizerEnabled = YES;
        _tapGestureRecognizerEnabled = YES;
    }
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];

    [self setupUI];
}

- (void)setupUI {
    self.view.backgroundColor = [UIColor whiteColor];

    // 添加手势
    self.pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(touchPan:)];
    [self.view addGestureRecognizer:self.pan];
    self.tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(touchTap:)];
    self.tap.delegate = self;
    [self.view addGestureRecognizer:self.tap];

    // 开启裁剪
    self.view.layer.masksToBounds = YES;
}

- (void)dealloc {
    // 移除手势
    [self.view removeGestureRecognizer:self.pan];
    [self.view removeGestureRecognizer:self.tap];

    // 移除当前控制器
    if (self.currentViewController) {
        [self.currentViewController.view removeFromSuperview];
        [self.currentViewController removeFromParentViewController];
        _currentViewController = nil;
    }

    // 移除临时控制器
    if (self.pendingViewController) {
        [self.pendingViewController.view removeFromSuperview];
        [self.pendingViewController removeFromParentViewController];
        self.pendingViewController = nil;
    }
}

#pragma mark - Public Mthod
- (void)setViewController:(UIViewController *)viewController {
    [self setViewController:viewController animated:NO isAbove:YES];
}

- (void)setViewController:(UIViewController *)viewController animated:(BOOL)animated isAbove:(BOOL)isAbove {
    if (!viewController) { return; }

    if (animated && self.currentViewController) { // 需要动画 同时有根控制器了
        // 正在动画
        if (self.isAnimateChange) { return; }

        self.isAnimateChange = YES;
        self.isTapLeft = isAbove;

        // 记录
        self.pendingViewController = viewController;

        // 添加
        [self addViewController:viewController];

        // 手势结束
        [self gestureSuccess:YES animated:YES];
    } else {

        // 添加
        [self addViewController:viewController];

        // 修改frame
        viewController.view.frame = self.view.bounds;

        // 当前控制器有值 进行删除
        if (_currentViewController) {
            [_currentViewController.view removeFromSuperview];
            [_currentViewController removeFromParentViewController];
        }

        // 赋值记录
        _currentViewController = viewController;
    }
}

#pragma mark - UIGestureRecognizerActions && UIGestureRecognizerDelegate
- (void)touchPan:(UIPanGestureRecognizer *)pan {
    // 用于辨别方向
    CGPoint tempPoint = [pan translationInView:self.view];

    // 用于计算位置
    CGPoint touchPoint = [pan locationInView:self.view];

    // 比较获取差值
    if (!CGPointEqualToPoint(self.moveTouchPoint, CGPointZero) &&
        (pan.state == UIGestureRecognizerStateBegan || pan.state == UIGestureRecognizerStateChanged)) {

        self.moveSpaceX = touchPoint.x - self.moveTouchPoint.x;
    }

    // 记录位置
    self.moveTouchPoint = touchPoint;

    if (pan.state == UIGestureRecognizerStateBegan) { // 手势开始
        // 正在动画
        if (self.openAnimate && self.isAnimateChange) { return; }

        self.isAnimateChange = YES;
        self.isPanBegin = YES;
        self.isPan = YES;
    } else if (pan.state == UIGestureRecognizerStateChanged) { // 手势移动
        if (fabs(tempPoint.x) < 0.01) { return; }

        // 滚动有值了
        if (self.isPanBegin) {
            self.isPanBegin = NO;
            // 获取将要显示的控制器
            self.pendingViewController = [self getPanViewControllerWithTouchPoint:tempPoint];

            // 将要显示的控制器
            if (self.delegate && [self.delegate respondsToSelector:@selector(coverViewController:willTransitionToPendingViewController:)]) {
                [self.delegate coverViewController:self willTransitionToPendingViewController:self.pendingViewController];
            }

            // 添加
            [self addViewController:self.pendingViewController];
        }

        // 判断显示
        if (self.openAnimate && self.isPan) {
            if (!self.pendingViewController) { return; }

            if (self.isTapLeft) {
                self.pendingViewController.view.frame = CGRectMake(touchPoint.x - kControllerWidth, 0, kControllerWidth, kControllerHeight);
            } else {
                self.currentViewController.view.frame = CGRectMake(tempPoint.x > 0 ? 0 : tempPoint.x, 0, kControllerWidth, kControllerHeight);
            }
        }
    } else { // 手势结束

        if (self.isPan) {
            // 结束pan手势
            self.isPan = NO;

            if (self.openAnimate) { // 动画

                if (self.pendingViewController) {
                    BOOL isSuccess = YES;
                    if (self.isTapLeft) {
                        if (self.pendingViewController.view.frame.origin.x <= -(kControllerWidth - kControllerWidth*0.18)) {
                            isSuccess = NO;
                        } else {
                            if (self.moveSpaceX < 0) {
                                isSuccess = NO;
                            }
                        }
                    } else {
                        if (self.currentViewController.view.frame.origin.x >= -1) {
                            isSuccess = NO;
                        }
                    }
                    [self gestureSuccess:isSuccess animated:YES];
                } else {
                    self.isAnimateChange = NO;
                }
            } else { // 无动画
                [self gestureSuccess:YES animated:NO];
            }
        }

        // 清空记录
        self.moveTouchPoint = CGPointZero;
        self.moveSpaceX = 0;
    }
}

- (void)touchTap:(UITapGestureRecognizer *)tap {
    // 正在动画
    if (self.openAnimate && self.isAnimateChange) { return; }

    self.isAnimateChange = YES;

    CGPoint touchPoint = [tap locationInView:self.view];

    // 获取将要显示的控制器
    self.pendingViewController = [self getTapViewControllerWithTouchPoint:touchPoint];

    // 将要显示的控制器
    if (self.delegate && [self.delegate respondsToSelector:@selector(coverViewController:willTransitionToPendingViewController:)]) {
        [self.delegate coverViewController:self willTransitionToPendingViewController:self.pendingViewController];
    }

    // 添加
    [self addViewController:self.pendingViewController];
    // 手势结束
    [self gestureSuccess:YES animated:self.openAnimate];
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {

    if ([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]] && [gestureRecognizer isEqual:self.tap]) {
        CGFloat tempX = kControllerWidth / 3;
        CGPoint touchPoint = [self.tap locationInView:self.view];
        if (touchPoint.x > tempX && touchPoint.x < (kControllerWidth - tempX)) {
            return YES;
        }
    }

    return NO;
}

#pragma mark - Private Method
/// 手势结束
- (void)gestureSuccess:(BOOL)isSuccess animated:(BOOL)animated {
    if (!self.pendingViewController) { return; }

    if (self.isTapLeft) { // 左边

        if (animated) {
            [UIView animateWithDuration:kAnimateDuration animations:^{
                if (isSuccess) {
                    self.pendingViewController.view.frame = CGRectMake(0, 0, kControllerWidth, kControllerHeight);
                } else {
                    self.pendingViewController.view.frame = CGRectMake(-kControllerWidth, 0, kControllerWidth, kControllerHeight);
                }
            } completion:^(BOOL finished) {
                [self animateSuccess:isSuccess];
            }];
        } else {
            if (isSuccess) {
                self.pendingViewController.view.frame = CGRectMake(0, 0, kControllerWidth, kControllerHeight);
            } else {
                self.pendingViewController.view.frame = CGRectMake(-kControllerWidth, 0, kControllerWidth, kControllerHeight);
            }
            [self animateSuccess:isSuccess];
        }
    } else { // 右边

        if (animated) {
            [UIView animateWithDuration:kAnimateDuration animations:^{
                if (isSuccess) {
                    self.currentViewController.view.frame = CGRectMake(-kControllerWidth, 0, kControllerWidth, kControllerHeight);
                } else {
                    self.currentViewController.view.frame = CGRectMake(0, 0, kControllerWidth, kControllerHeight);
                }
            } completion:^(BOOL finished) {
                [self animateSuccess:isSuccess];
            }];
        } else {
            if (isSuccess) {
                self.currentViewController.view.frame = CGRectMake(-kControllerWidth, 0, kControllerWidth, kControllerHeight);
            } else {
                self.currentViewController.view.frame = CGRectMake(0, 0, kControllerWidth, kControllerHeight);
            }
            [self animateSuccess:isSuccess];
        }

    }
}

/// 动画结束
- (void)animateSuccess:(BOOL)isSuccess {

    if (isSuccess) {
        [self.currentViewController.view removeFromSuperview];
        [self.currentViewController removeFromParentViewController];
        _currentViewController = self.pendingViewController;
        self.pendingViewController = nil;
        self.isAnimateChange = NO;
    } else {
        [self.pendingViewController.view removeFromSuperview];
        [self.pendingViewController removeFromParentViewController];
        self.pendingViewController = nil;
        self.isAnimateChange = NO;
    }

    // 代理回调
    if (self.delegate && [self.delegate respondsToSelector:@selector(coverViewController:currentViewController:didFinishAnimating:)]) {
        [self.delegate coverViewController:self currentViewController:self.currentViewController didFinishAnimating:isSuccess];
    }
}

/**
 根据点击手势触发的位置获取控制器

 @param touchPoint 手势触发位置
 @return 需要显示的控制器
 */
- (UIViewController * _Nullable)getTapViewControllerWithTouchPoint:(CGPoint)touchPoint {
    UIViewController *vc = nil;

    if (touchPoint.x < kControllerWidth / 3) { // 左边

        self.isTapLeft = YES;
        // 获取上一个显示控制器
        if (self.delegate && [self.delegate respondsToSelector:@selector(coverViewController:viewControllerBeforeCurrentViewController:)]) {
            vc = [self.delegate coverViewController:self viewControllerBeforeCurrentViewController:self.currentViewController];
        }

    } else if (touchPoint.x > (kControllerWidth - kControllerWidth / 3)) { // 右边

        self.isTapLeft = NO;
        // 获取下一个显示控制器
        if (self.delegate && [self.delegate respondsToSelector:@selector(coverViewController:viewControllerAfterCurrentViewController:)]) {
            vc = [self.delegate coverViewController:self viewControllerAfterCurrentViewController:self.currentViewController];
        }
    }

    if (!vc) {
        self.isAnimateChange = NO;
    }

    return vc;
}

/**
 根据拖动手势触发的位置获取控制器

 @param touchPoint 手势触发位置
 @return 需要显示的控制器
 */
- (UIViewController * _Nullable)getPanViewControllerWithTouchPoint:(CGPoint)touchPoint {
    UIViewController *vc = nil;

    if (touchPoint.x > 0) { // 左边

        self.isTapLeft = YES;
        // 获取上一个显示控制器
        if (self.delegate && [self.delegate respondsToSelector:@selector(coverViewController:viewControllerBeforeCurrentViewController:)]) {
            vc = [self.delegate coverViewController:self viewControllerBeforeCurrentViewController:self.currentViewController];
        }

    } else { // 右边

        self.isTapLeft = NO;
        // 获取下一个显示控制器
        if (self.delegate && [self.delegate respondsToSelector:@selector(coverViewController:viewControllerAfterCurrentViewController:)]) {
            vc = [self.delegate coverViewController:self viewControllerAfterCurrentViewController:self.currentViewController];
        }
    }

    if (!vc) {
        self.isAnimateChange = NO;
    }

    return vc;
}


/// 添加控制器
- (void)addViewController:(UIViewController *)viewController {
    if (!viewController) { return; }

    [self addChildViewController:viewController];

    if (self.isTapLeft) { // 左边

        [self.view addSubview:viewController.view];
        viewController.view.frame = CGRectMake(-kControllerWidth, 0, kControllerWidth, kControllerHeight);
    } else { // 右边

        if (self.currentViewController) {
            [self.view insertSubview:viewController.view belowSubview:self.currentViewController.view];
        } else {
            [self.view addSubview:viewController.view];
        }
        viewController.view.frame = CGRectMake(0, 0, kControllerWidth, kControllerHeight);
    }

    // 添加阴影
    if (self.openAnimate) {
        [self addShadowViewController:viewController];
    }
}

/// 给控制器阴影
- (void)addShadowViewController:(UIViewController *)viewController {
    if (!viewController) { return; }

    viewController.view.layer.shadowColor = [UIColor blackColor].CGColor; // 阴影颜色
    viewController.view.layer.shadowOffset = CGSizeMake(0, 0); // 偏移距离
    viewController.view.layer.shadowOpacity = 0.5; // 不透明度
    viewController.view.layer.shadowRadius = 10.0; // 半径
}

#pragma mark - Setter
- (void)setPanGestureRecognizerEnabled:(BOOL)panGestureRecognizerEnabled {
    _panGestureRecognizerEnabled = panGestureRecognizerEnabled;
    self.pan.enabled = panGestureRecognizerEnabled;
}

- (void)setTapGestureRecognizerEnabled:(BOOL)tapGestureRecognizerEnabled {
    _tapGestureRecognizerEnabled = tapGestureRecognizerEnabled;
    self.tap.enabled = tapGestureRecognizerEnabled;
}

@end
